/**
 * Author: meimeidev
 */
$().ready( function() {
	/**
	var h = $(window).height()-$(".bar").height()-$(".ctl-filter").outerHeight(true)-10;
	if(parent.location.href.indexOf("list_tb")>=0){
		h=h-2;
	}*/
	var $responsive = $(".table-responsive");
	if($responsive.length>0){
		var top = $responsive.offset().top; 
		var h = $(window).height()-top;
		if(parent.location.href.indexOf("list_tb")>=0){
			h=h-4;
		}
		$responsive.height(h);
	}
	
	
})
!function($){
	
    var MMGrid = function (element, options) {
        this._id = (((1 + Math.random()) * 0x10000) | 0).toString(16);
        this._loadCount = 0;
        this.selecteds = [];
        this.opts = options;
        this._initLayout($(element));
       	this._initHead();
        this._initOptions();
        this._initEvents();
        this._setColsWidth();
        if(this.opts.fullWidthRows){
            this._fullWidthRows();
        }
        
        //初始化插件
        for(var i=0; i< this.opts.plugins.length; i++){
            var plugin = this.opts.plugins[i];
            plugin.init($.extend(element, this),this);
        }
		var that = this;
        if(options.autoLoad){
            this.opts = options;
            setTimeout(function(){

                if(options.url){
                    that.load();
                }else{
                    that.load(options.items);
                }
            },0); //chrome style problem
        }
        if(this.$mmPaginator!=undefined){
        	//$("#body-paginator").insertAfter($("table.mmg-body"));
        	this.$mmPaginator.parent().insertAfter(this.$body);
        }
		
		if(options.bindSearchBtn){
			this.searchBtn = $("#searchBtn");
			this.searchBtn.unbind("click").bind("click",function(){
		    	that.load({pageNumber:1});
		    });
		}
		
	    if(options.useCountText==true){
	    	var html='<div class="floatDiv" style="position:fixed;top:0;right:160px;height:38px;text-align:right;"><p class="checked-p" style="line-height:38px;font-size:14px;">当前页共有 <span class="currentPageRecords" style="color:blue">0</span> 条记录，已勾选 <span class="recordsChecked" style="color:blue">0</span> 条记录</p></div>';
	 		$("#listForm").append(html);
	    }
	    
	     if(options.hideHead){
	     	var $headWrapper = this.$headWrapper;
	     	var $bodyWrapper = this.$bodyWrapper;
           	$bodyWrapper.height($bodyWrapper.height()+$headWrapper.outerHeight(true))
           	 $headWrapper.hide();
         }
    };

    //see: http://tanalin.com/en/articles/ie-version-js/
    var browser = function(){
        var isIE=!!window.ActiveXObject;
        var isIE10 = isIE && !!window.atob;
        var isIE9 = isIE && document.addEventListener && !window.atob;
        var isIE8 = isIE && document.querySelector && !document.addEventListener;
        var isIE7 = isIE && window.XMLHttpRequest && !document.querySelector;
        var isIE6 = isIE && !window.XMLHttpRequest;

        return {
            isIE: isIE
            , isIE6: isIE6
            , isIE7: isIE7
            , isIE8: isIE8
            , isIE9: isIE9
            , isIE10: isIE10
        };
    }();

    MMGrid.prototype = {

        _initLayout: function($el){
            var opts = this.opts;
            var $elParent = $el.parent();
            var elIndex = $el.index();

            var mmGrid = [
                '<div class="mmGrid">',
                    '<style></style>',
                    '<div class="mmg-headWrapper">',
                        '<table class="mmg-head" cellspacing="0"></table>',
                    '</div>',
                    '<div class="mmg-colResizePointer"></div>',
                    '<div class="mmg-colResizePointer-before"></div>',
                    '<div class="mmg-backboard">',
                        '<a class="mmg-btnBackboardUp"></a>',
                    '</div>',
                    '<div class="mmg-bodyWrapper"></div>',
                    '<a class="mmg-btnBackboardDn"></a>',
                    '<div class="mmg-message">'+ this.opts.noDataText +'</div>',
                    '<div class="mmg-mask mmg-transparent"></div>',
                    '<div class="mmg-loading">',
                        '<div class="mmg-loadingImg"></div>',
                        '<div class="mmg-loadingText">'+ this.opts.loadingText +'</div>',
                    '</div>',

                '</div>'
            ];
            //fix in IE7,IE6
            if(browser.isIE7 || browser.isIE6){
                $el.prop('cellspacing',0);
            }


            //cached object
            var $mmGrid = $(mmGrid.join(''));
            this.$mmGrid = $mmGrid;
            this.$style = $mmGrid.find('style');
            this.$headWrapper = $mmGrid.find('.mmg-headWrapper');
            this.$head = $mmGrid.find('.mmg-head');
            this.$backboard = $mmGrid.find('.mmg-backboard');
            this.$bodyWrapper = $mmGrid.find('.mmg-bodyWrapper');
            this.$body = $el.removeAttr("style").addClass('mmg-body');
            this._insertEmptyRow();
            //this.$body.appendTo(this.$bodyWrapper);
			this.$bodyWrapper.prepend(this.$body);


            //放回原位置
            if(elIndex === 0 || $elParent.children().length == 0){
                $elParent.prepend(this.$mmGrid);
            }else{
                $elParent.children().eq(elIndex-1).after(this.$mmGrid);
            }


            // fix in ie6
            if(browser.isIE6 && (!opts.width || opts.width === 'auto')){
                $mmGrid.width('100%');
                $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width()));
            }else{
                $mmGrid.width(opts.width);
            }

			if(!opts.height || opts.height === 'fill'){
                $mmGrid.height('100%');
                $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height()));
            }else{
                $mmGrid.height(opts.height);
            }

            if(opts.checkCol){
            	var that = this;
            	var recordField = opts.recordField;
            	var recordRowId = opts.recordRowId;
            	
                var chkHtml = opts.multiSelect ?  '<input type="checkbox" class="checkAll" >'
                    : '<input type="checkbox" disabled="disabled" class="checkAll">';
                opts.cols.unshift({title:chkHtml,width: 20, align: 'center' ,lockWidth: true, checkCol: true, renderer:function(val,item,rowIndex){
                	var str = '';
                	if(recordRowId){
						if(that.selecteds.contains(item[recordField])){
							str = 'checked';
						}
					}
					if(opts.checkDisabled==true || (typeof opts.checkDisabled =='function' && opts.checkDisabled(item,rowIndex)==true)){
						str+=' disabled'
					}
                    return '<input type="checkbox" class="mmg-check" '+str+'>';
                }});
            }

            if(opts.indexCol){
                opts.cols.unshift({title:'#',width: opts.indexColWidth, align: 'center' ,lockWidth: true, indexCol:true, renderer:function(val,item,rowIndex){
                    return '<label class="mmg-index">' + (rowIndex+1) + '</label>';
                }});
            }

        }

        ,_expandCols: function(cols){
            var newCols = [];
            if(!cols){
               return newCols;
            }
            for(var colIndex=0; colIndex<cols.length; colIndex++){
               var col = cols[colIndex];
               if(col.cols){
                   newCols.push(col);
                   newCols.push.apply(newCols,this._expandCols(col.cols));
               }else{
                   newCols.push(col);
               }
            }
            return newCols;
        }
        ,_leafCols: function(){
            var opts = this.opts;
            var newCols = [];
            var cols = this._expandCols(opts.cols);
            for(var colIndex=0; colIndex<cols.length; colIndex++){
                var col = cols[colIndex];
                if(!col.cols){
                    newCols.push(col);
                }
            }
            return newCols;
        }

        ,_expandThs: function(){
            return this.$head.find('th').sort(function(a, b){
               return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex'));
            });
        }

        ,_leafThs: function(){
            return this.$head.find('th').filter(function(){
                return !$.data(this,'col').cols;
            }).sort(function(a, b){
                return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex'));
            });
        }


        ,_colsWithTitleDeep: function(cols,deep){
            var newCols = [];
            if(!cols){
                return newCols;
            }
            for(var colIndex=0; colIndex<cols.length; colIndex++){
                var col = cols[colIndex];
                if(deep === 1){
                    newCols.push(col);
                }else{
                    newCols.push.apply(newCols, this._colsWithTitleDeep(col.cols, deep-1));
                }
            }
            return newCols;
        }

        ,_titleDeep: function(cols){
            var deep = 1;
            for(var colIndex=0; colIndex<cols.length; colIndex++){
                var col = cols[colIndex];
                if(col.cols){
                    var newDeep = 1 + this._titleDeep(col.cols);
                    if(deep < newDeep){
                        deep = newDeep;
                    }
                }
            }
            return deep;
        }

        , _titleHtml: function(col, rowspan){
            var opts = this.opts;

            var titleHtml = [];
            if(!col.cols){
                titleHtml.push('<th class="');
                var colIndex =  $.inArray(col, this._expandCols(opts.cols));
                titleHtml.push(this._genColClass(colIndex));
                if(rowspan>1){
                	titleHtml.push(' merge-row');
                }
                titleHtml.push(' " ');
                titleHtml.push(' rowspan="');
                titleHtml.push(rowspan);
                titleHtml.push('" colspan="');
                titleHtml.push(1);
                titleHtml.push('" data-colIndex="');
                titleHtml.push(colIndex);
                titleHtml.push('" >');
                titleHtml.push('<div class="mmg-titleWrapper" >');
                titleHtml.push('<span class="mmg-title ');
                if(col.sortable) titleHtml.push('mmg-canSort ');
                titleHtml.push('">');
                if(col.titleHtml){
                    titleHtml.push(col.titleHtml);
                }else{
                    titleHtml.push(col.title);
                }
                titleHtml.push('</span><div class="mmg-sort"></div>');
                if(!col.lockWidth) titleHtml.push('<div class="mmg-colResize"></div>');
                titleHtml.push('</div></th>');
            }else{
                var displayColsLength = col.cols.length;
                $.each(col.cols, function(index, item){
                    if(item.hidden){
                        displayColsLength--;
                    }
                });
                if(displayColsLength === 0){
                    col.hidden = true;
                }
                titleHtml.push('<th class="');
                var colIndex =  $.inArray(col, this._expandCols(opts.cols));
                titleHtml.push(this._genColClass(colIndex));
                titleHtml.push(' mmg-groupCol" ');
                titleHtml.push(' rowspan="');
                titleHtml.push(rowspan-1);
                titleHtml.push('" colspan="');
                titleHtml.push(displayColsLength);
                titleHtml.push('" data-colIndex="');
                titleHtml.push(colIndex);
                titleHtml.push('" >');
                titleHtml.push('<div class="mmg-titleWrapper" >');
                titleHtml.push('<span class="mmg-title ');
                if(col.sortable) titleHtml.push('mmg-canSort ');
                titleHtml.push('">');
                if(col.titleHtml){
                    titleHtml.push(col.titleHtml);
                }else{
                    titleHtml.push(col.title);
                }
                titleHtml.push('</span><div class="mmg-sort"></div>');
                titleHtml.push('</div></th>');
            }

            return titleHtml.join("");
        }

        , _initHead: function(){
            var that = this;
            var opts = this.opts;
            var $head = this.$head;

            if(opts.cols){
                var theadHtmls = ['<thead>'];

                //获取标题深度
                var titleDeep = that._titleDeep(opts.cols);
                for(var deep=1; deep<= titleDeep; deep++){
                    var cols = that._colsWithTitleDeep(opts.cols, deep);
                    theadHtmls.push('<tr>');
                    for(var colIndex=0; colIndex< cols.length; colIndex++){
                        var col = cols[colIndex];
                        theadHtmls.push(this._titleHtml(col, titleDeep-deep+1));
                    }
                    theadHtmls.push('</tr>');
                }
                theadHtmls.push('</thead>');
                $head.html(theadHtmls.join(''));
            }

            var $ths = this._expandThs();
            var expandCols = this._expandCols(opts.cols);
            $.each($ths,function(index){
                if(!expandCols[index].width){
                    expandCols[index].width = 100;
                }
                $.data(this,'col-width',expandCols[index].width);
                $.data(this,'col',expandCols[index]);
            });
            
            var $mmGrid = this.$mmGrid;
            var $headWrapper = this.$headWrapper;
            var $bodyWrapper = this.$bodyWrapper;
            if(opts.height=='auto'){
            	$bodyWrapper.height('auto');
            }else{
	            $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true));
			}


            //初始化排序状态
            if(opts.sortName){
                for(var colIndex=0; colIndex< expandCols.length; colIndex++){
                    var col = expandCols[colIndex];
                    if(col.sortName === opts.sortName || col.name === opts.sortName){
                        var $th= $ths.eq(colIndex);
                        $.data($th.find('.mmg-title')[0],'sortStatus',opts.sortStatus);
                        $th.find('.mmg-sort').addClass('mmg-'+opts.sortStatus);
                    }
                }
            }
        }

        , _initOptions: function(){
            var opts = this.opts;
            var $mmGrid = this.$mmGrid;
            var $headWrapper = this.$headWrapper;
            var $backboard = this.$backboard;
            $mmGrid.find('a.mmg-btnBackboardDn').css({
                'top': $headWrapper.outerHeight(true)
            }).slideUp('fast');

            var cols = this._leafCols();
            if(cols){
                var bbHtml = ['<h1>显示列</h1>'];
                for(var colIndex=0; colIndex<cols.length; colIndex++){
                    bbHtml.push('<label ');
                    if(cols[colIndex].checkCol || cols[colIndex].indexCol){
                        bbHtml.push('style="display:none;" ');
                    }
                    var col = cols[colIndex];
                    bbHtml.push('><input type="checkbox"  ');
                    if(!col.hidden) bbHtml.push('checked="checked"');
                    if(col.lockDisplay) bbHtml.push(' disabled="disabled"');
                    bbHtml.push('/><span>');
                    if(col.title){
                        bbHtml.push(col.title);
                    }else{
                        bbHtml.push('未命名');
                    }

                    bbHtml.push('</span></label>');
                }
                $backboard.append($(bbHtml.join('')));
            }
        }

        , _initEvents: function(){
            var that = this;
            var opts = this.opts;
            var $mmGrid = this.$mmGrid;
            var $headWrapper = this.$headWrapper;
            var $head = this.$head;
            var $bodyWrapper = this.$bodyWrapper;
            var $body = this.$body;
            var $backboard = this.$backboard;
            var $ths = this._expandThs();
            var expandCols = this._expandCols(opts.cols);
            var leafCols = this._leafCols();

            //调整浏览器
            if(opts.width === 'auto' || opts.height === 'auto'|| opts.height === 'fill' || (typeof opts.width === 'string' && opts.width.indexOf('%') === opts.width.length-1) ||
                typeof opts.height === 'string' && opts.height.indexOf('%') === opts.height.length-1){
                $(window).on('resize', function(){
                    that.resize();
                });
            }

            //滚动条事件
            $bodyWrapper.on('scroll', function(){
                $head.css('left',- $(this).scrollLeft());
            });

            //向下按钮
            var $btnBackboardDn = $mmGrid.find('a.mmg-btnBackboardDn').on('click', function(){
                var backboardHeight = $mmGrid.height() - $headWrapper.outerHeight(true);
                if(opts.height === 'auto'&& opts.backboardMinHeight !== 'auto' && backboardHeight < opts.backboardMinHeight){
                    backboardHeight = opts.backboardMinHeight;
                }
                $backboard.height(backboardHeight);
                if(opts.height === 'auto'){
                    $mmGrid.height($headWrapper.outerHeight(true) + $backboard.outerHeight(true));
                }
                $backboard.slideDown();
                $btnBackboardDn.slideUp('fast');

                that._hideMessage();
            });
            $body.on('mouseenter', function(){
                $btnBackboardDn.slideUp('fast');
            });
            $mmGrid.on('mouseleave', function(){
                $btnBackboardDn.slideUp('fast');
            });
            $headWrapper.on('mouseenter',function(){
                if($backboard.is(':hidden') && opts.showBackboard){
                    $btnBackboardDn.slideDown('fast');
                }
            });
            //向上按钮
            $mmGrid.find('a.mmg-btnBackboardUp').on('click', function(){
                $backboard.slideUp().queue(function(next){
                    if(!that.rowsLength() || (that.rowsLength() === 1 && $body.find('tr.emptyRow').length === 1)){
                        that._showNoData();
                    }
                    if(opts.height === 'auto'){
                        $mmGrid.height('auto');
                    }
                    next();
                });
            });

            //隐藏列
            $backboard.on('click', ':checkbox', function(){
                var index = $backboard.find('label').index($(this).parent());
                //最后一个不隐藏
                var last = 1;
                if(opts.checkCol){
                    last = last + 1;
                }
                if(opts.indexCol){
                    last = last + 1;
                }
                if($backboard.find('label :checked').length < last){
                    this.checked = true;
                    return;
                }

                var col = leafCols[index];
                if(this.checked){
                    col.hidden = false;

                }else{
                    col.hidden = true;
                }

                var $ths = $head.find('th');
                for(var colIndex=$ths.length-1; colIndex>=0; colIndex--){
                    var $th = $ths.eq(colIndex);
                    var iCol = $th.data('col');
                    if(iCol.cols){
                        var hidden = true;
                        var colspan = 0;
                        $.each(iCol.cols,function(index,item){
                            if(!item.hidden){
                                hidden = false;
                                colspan++;
                            }
                        });
                        //IE bug
                        if(colspan !== 0){
                            $th.prop('colspan',colspan);
                        }
                        iCol.hidden = hidden;
                    }
                }

                that._setColsWidth();
                $backboard.height($mmGrid.height() - $headWrapper.outerHeight(true));
                if(opts.height=='auto'){
                	$bodyWrapper.height('auto');
                }else{
                	$bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)-5);
                }
                $mmGrid.find('a.mmg-btnBackboardDn').css({
                    'top': $headWrapper.outerHeight(true)
                })
            });



            //排序事件
            $head.on('click', '.mmg-title', function(){
                var $this = $(this);
                var $titles =  $ths.find('.mmg-title');

                //当前列不允许排序
                var col =$this.parent().parent().data('col');
                if(!col.sortable){
                    return;
                }
                //取得当前列下一个排序状态
                var sortStatus = $.data(this, 'sortStatus') === 'asc' ? 'desc' : 'asc';
                //清除排序状态
                $.each($titles, function(){
                    $.removeData(this,'sortStatus');
                });
                $ths.find('.mmg-sort').removeClass('mmg-asc').removeClass('mmg-desc');
                //设置当前列排序状态
                $.data(this, 'sortStatus', sortStatus);
                $this.siblings('.mmg-sort').addClass('mmg-'+sortStatus);

                if(opts.url && opts.remoteSort){
                    that.load()
                }else{
                    that._nativeSorter($.inArray(col, leafCols), sortStatus);
                    that._setStyle();
                }
            }).on('mousedown', '.mmg-colResize', function(e){
                //调整列宽
                var $resize = $(this);
                var start = e.pageX;
                var $colResizePointer = $mmGrid.find('.mmg-colResizePointer')
                    .css('left', e.pageX - $headWrapper.offset().left).show();

                var scrollLeft = $head.position().left;
                var $colResizePointerBefore = $mmGrid.find('.mmg-colResizePointer-before')
                    .css('left', $resize.parent().parent().position().left + scrollLeft).show();
                //取消文字选择
                document.selection && document.selection.empty && ( document.selection.empty(), 1)
                || window.getSelection && window.getSelection().removeAllRanges();
                document.body.onselectstart = function () {
                    return false;
                };
                $headWrapper.css('-moz-user-select','none');

                $mmGrid.on('mousemove', function(e){
                    $colResizePointer.css('left', e.pageX - $headWrapper.offset().left);
                }).on('mouseup', function(e){
                    //改变宽度
                    var $th = $resize.parent().parent();
                    var width = $th.width() + e.pageX - start;
                    $.data($th[0], 'col-width', width);
                    that._setColsWidth();
                    $headWrapper.mouseleave();
                }).on('mouseleave',function(){
                    $mmGrid.off('mouseup').off('mouseleave').off('mousemove');
                    $colResizePointer.hide();
                    $colResizePointerBefore.hide();
                    document.body.onselectstart = function(){
                        return true;//开启文字选择
                    };
                    $headWrapper.css('-moz-user-select','text');
                });
            });

            //选中事件
            var $body = this.$body;
            if(opts.checkByClickTd){
	            $body.on('click','td',function(e){
	                var $this = $(this);
	                var event = jQuery.Event("cellSelected");
	                event.target = e.target;
	                that.$body.triggerHandler(event, [$.data($this.parent()[0], 'item'), $this.parent().index(), $this.index()]);
	
	                if(event.isPropagationStopped()){
	                }else{
	                	if(!$this.parent().hasClass('selected')){
		                    that.select($this.parent().index());
		                }else{
		                    that.deselect($this.parent().index());
		                }
	                }
	                if(opts.useCountText){
	                	var selectedNum = that.selectedRows().length;
						$(".recordsChecked").text(selectedNum);
	                }
	            });
            }

            $body.on('click','tr > td .mmg-check',function(e){
            	if(opts.checkByClickTd){
                	e.stopPropagation();
                }
                var $this = $(this);
                if(this.checked){
                    that.select($($this.parents('tr')[0]).index());
                }else{
                    that.deselect($($this.parents('tr')[0]).index());
                }
                if(opts.useCountText){
                	var selectedNum = that.selectedRows().length;
					$(".recordsChecked").text(selectedNum);
                }
                
            });

            //checkbox列
            if(opts.checkCol){
                $head.find('th .checkAll').on('click', function(){
                    if(this.checked){
                        that.select('all');
                    }else{
                        that.deselect('all');
                    }
                    if(opts.useCountText){
	                	var selectedNum = that.selectedRows().length;
						$(".recordsChecked").text(selectedNum);
	                }
                });
            }

            //IE6不支持hover
            if (browser.isIE6){
                $body.on('mouseenter','tr', function () {
                    $(this).toggleClass('hover');
                }).on('mouseleave','tr', function () {
                    $(this).toggleClass('hover');
                });
            };


        }

        , _rowHtml: function(item, rowIndex, obj){
            var opts = this.opts;
            var expandCols = this._expandCols(opts.cols);
            var leafCols = this._leafCols();
			var rowCursorPointer = opts.rowCursorPointer;
			var lineRoot = opts.lineRoot;
			var rowspan = 1;
			
            if($.isPlainObject(item)){
               
				var opts = this.opts;
				var lines;
				if(lineRoot!=undefined){
					lines = item[lineRoot];
					if(lines!=undefined && lines.length>1){
						rowspan = lines.length;
					}
					
				}
				
				 var trHtml = [];	
				
				var str_pounter = (rowCursorPointer)?'row-cp':'';
				
                trHtml.push('<tr class="real-row '+str_pounter+'" rowIndex="'+rowIndex+'">');
                for(var colIndex=0; colIndex < leafCols.length; colIndex++){
                    var col = leafCols[colIndex];
					
					var usedItem;
					var rowspan_str = ''
					if(col.isLines!=undefined && col.isLines==true){
						if(lines!=undefined && lines.length>0){
							usedItem = lines[0];
						}
					}else{
						usedItem = item;
						rowspan_str = 'rowspan="'+rowspan+'"';
					}
					
                    trHtml.push('<td '+rowspan_str+' class="');
                    var index =  $.inArray(col, expandCols);
                    trHtml.push(this._genColClass(index));
                    if(col.nowrap==false && rowspan>1){
                    
                    }else if(opts.nowrap){
                        trHtml.push(' nowrap');
                    }
                    trHtml.push('"><span class="');
                    if(col.nowrap==false && rowspan>1){
                    	trHtml.push('txt-newline" style="-webkit-line-clamp:'+rowspan+';">');
                    }else if(opts.nowrap){
                        trHtml.push('nowrap">');
                    }
                    //trHtml.push('">');
					
					if(usedItem!=undefined){
						var val_str = usedItem[col.name];
						if(val_str==null){
							val_str='';
							usedItem[col.name]='';
						}
						if(col.renderer){
							trHtml.push(col.renderer(val_str,usedItem,rowIndex,obj));
						}else{
							trHtml.push(val_str);
						}
					}
                    

                    trHtml.push('</span></td>');
                };
                trHtml.push('</tr>');
				
				var row_cp_str = (rowCursorPointer)?'class="row-cp"':'';
				 if(lines!=undefined && lines.length>1){
					 for(var i=1;i<rowspan;i++){
						var line = lines[i];
						trHtml.push('<tr '+row_cp_str+' rowIndex="'+rowIndex+'">');
						for(var colIndex=0; colIndex < leafCols.length; colIndex++){
							var col = leafCols[colIndex];
							if(col.isLines!=undefined && col.isLines==true){
								trHtml.push('<td class="');
								var index =  $.inArray(col, expandCols);
								trHtml.push(this._genColClass(index));
								if(opts.nowrap){
									trHtml.push(' nowrap');
								}
								trHtml.push('"><span class="');
								if(opts.nowrap){
									trHtml.push('nowrap');
								}
								trHtml.push('">');
								
								var val_str = line[col.name];
								if(val_str==null){
									val_str='';
									line[col.name]='';
								}
								if(col.renderer){
									trHtml.push(col.renderer(val_str,line,rowIndex,obj));
								}else{
									trHtml.push(val_str);
								}

								trHtml.push('</span></td>');
							}
							
						 }
						 trHtml.push('</tr>');
					 }
				 }
				
                return trHtml.join('');
            }
        }

        , _populate: function(items){
            var opts = this.opts;
            var $body = this.$body;

            this._hideMessage();
            if(items && items.length !== 0 && opts.cols){

                var tbodyHtmls = [];
                tbodyHtmls.push('<tbody>');
                if(opts.renderer){
                	var $tr = $(this._rowHtml(items[0], 0));
                	var $td = $tr.find("td");
                	$td.attr("style","border-bottom: none;background:none !important;");
                	var contentHtml = opts.renderer(items);
                	$td.empty().html(contentHtml);
                	tbodyHtmls.push($tr.prop("outerHTML"));
                }else{
                	for(var rowIndex=0; rowIndex < items.length; rowIndex++){
	                    var item = items[rowIndex];
	                    tbodyHtmls.push(this._rowHtml(item, rowIndex));
	                }
                }
                tbodyHtmls.push('</tbody>');
                $body.empty().html(tbodyHtmls.join(''));
                if(!opts.renderer){
	                var $trs = $body.find('tr.real-row');
	                for(var rowIndex=0; rowIndex < items.length; rowIndex++){
	                    $.data($trs.eq(rowIndex)[0],'item',items[rowIndex]);
	                }
                }
            }else{
                this._insertEmptyRow();
                this._showNoData();
            }
            this._setStyle();

            if(opts.fullWidthRows && this._loadCount <= 1){
                this._fullWidthRows();
            }
            
             if(opts.useCountText){
				$(".currentPageRecords").text(items.length);
				$(".recordsChecked").text(0);
             }
             
            if(opts.checkCol && opts.multiSelect && opts.recordRowId){
             	var $head = this.$head;
                var $checks = $body.find('tr > td').find('.mmg-check');
                var $checkeds = $checks.filter(':checked');
                $checkeds.closest("tr").addClass("selected");
                var checkedSize = $checkeds.length;
                if(checkedSize>0 && $checks.length === checkedSize){
                    $head.find('th .checkAll').prop('checked','checked');
                }else{
                	$head.find('th .checkAll').prop('checked','');
                }
                if(opts.useCountText){
                	$(".recordsChecked").text(checkedSize);
                }
            }
            
        }

        , _insertEmptyRow: function(){
            var $body = this.$body;
            $body.empty().html('<tbody><tr class="emptyRow"><td  style="border: 0px;background: none;">&nbsp;</td></tr></tbody>');
        }
        , _removeEmptyRow: function(){
            var $body = this.$body;
            $body.find('tr.emptyRow').remove();
        }

        /* 生成列类 */
        , _genColClass: function(colIndex){
            return 'mmg'+ this._id +'-col'+colIndex;
        }

        , _setStyle: function(){
            var $head = this.$head;
            var $ths = this._expandThs();
            var $body = this.$body;
            var leafCol = this._leafCols();

            //head
            $ths.eq(0).addClass('first');
            $ths.eq(-1).addClass('last');
            //body
            $body.find('tr,td').removeClass('even')
                .removeClass('colSelected').removeClass('colSelectedEven');

            //$body.find('tr:odd').addClass('even');
            $body.find('tr').each(function(){
            	if(Number($(this).attr('rowindex'))%2==1){
            		$(this).addClass('even');
            	}
            	
            });



            var sortIndex = $.inArray($head.find('.mmg-title').filter(function(){
                return $.data(this,'sortStatus') === 'asc' || $(this).data('sortStatus') === 'desc';
            }).parent().parent().data('col'), leafCol);

            $body.find('tr > td:nth-child('+(sortIndex+1)+')').addClass('colSelected')
                .filter(':odd').addClass('colSelectedEven');

            this._resizeHeight();

        }
        , _setColsWidth: function(){
            var opts = this.opts;
            var $style = this.$style;
            var $head = this.$head;

            var $bodyWrapper = this.$bodyWrapper;
            var $body = this.$body;
            var $ths = this._expandThs();
            var expandCols = this._expandCols(opts.cols);

            var scrollTop = $bodyWrapper.scrollTop();
            var scrollLeft = $head.position().left;

            $bodyWrapper.width(9999);
            $body.width('auto');
            var styleText = [];
            for(var colIndex=0; colIndex<$ths.length; colIndex++){
                var $th = $ths.eq(colIndex);
                styleText.push('.mmGrid .'+this._genColClass(colIndex) + ' {');
                var width = $.data($th[0],'col-width');
                styleText.push('width: '+ width +'px;');
                styleText.push('max-width: '+ width +'px;');

                var col = expandCols[colIndex];
                
                if(col.align){
                    styleText.push('text-align: '+col.align+';');
                }
                if(col.hidden){
                    styleText.push('display: none; ');
                }
                
                styleText.push(' }');
                
                /**
                if(col.isLines==true){
                	var str = '';
                	if(col.isBegin==true){
                		str+='border-left: solid 1px #E9E9E9;';
                	}
                	if(col.isEnd==true){
                		str+='border-right: solid 1px #E9E9E9;'
                	}
                	if(str.length>0){
                		styleText.push('.mmGrid td.'+this._genColClass(colIndex) + '{'+str+'}');
                	}
                }*/
            }

			if(opts.height=='auto'){
				scrollTop = $("body").scrollTop();
			}

            $body.detach();
            try{
                $style.text(styleText.join(''));
            }catch(error){
                $style[0].styleSheet.cssText = styleText.join('');//IE fix
            }
            $body.width($head.width());
            $bodyWrapper.width('100%');
            $bodyWrapper.prepend($body);

            //调整滚动条

            $bodyWrapper.scrollLeft(-scrollLeft);
            if($bodyWrapper.scrollLeft() === 0){
                $head.css('left', 0);
            }
			if(opts.height=='fill'){
            	$bodyWrapper.scrollTop(scrollTop);
            }else if(opts.height=='auto'){
            	$("body").scrollTop(scrollTop);
            }
        }
        , _fullWidthRows: function(){
            var opts = this.opts;
            var $bodyWrapper = this.$bodyWrapper;
            var $mmGrid = this.$mmGrid;
            var $head = this.$head;
            var scrollWidth = $bodyWrapper.width() - $bodyWrapper[0].clientWidth;

            if(scrollWidth && browser.isIE){
                scrollWidth = scrollWidth + 1;
            }

            var fitWidth =  $mmGrid.width() - $head.width() - scrollWidth;
            if(fitWidth < -20){
                return;
            }

            var thsArr = [];
            var $ths = this._leafThs();
            var leafCol = this._leafCols();
            for(var i=0; i< leafCol.length; i++){
                var col = leafCol[i];
                var $th = $ths.eq(i);
                if(!col.lockWidth && $th.is(':visible') || (opts.hideHead)){
                    thsArr.push($th);
                }
            }

            var increaseWidth =  Math.floor(fitWidth / thsArr.length);
            var maxColWidthIndex = 0;
            for(var i=0; i< thsArr.length; i++){
                var $th = thsArr[i];
                var colWidth = $.data($th[0], 'col-width') + increaseWidth;
                $.data($th[0], 'col-width', colWidth);

                var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width');
                if(maxColWidth < colWidth){
                    maxColWidthIndex = i;
                }
            }
			if(thsArr.length>0 && maxColWidthIndex!=undefined ){
				 var remainWidth =  fitWidth -  increaseWidth * thsArr.length;
            var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width');
            $.data(thsArr[maxColWidthIndex][0], 'col-width', maxColWidth + remainWidth);
			}
           
            this._setColsWidth();
        }


        , _showLoading: function(){
            var $mmGrid = this.$mmGrid;
            $mmGrid.find('.mmg-mask').show();

            var $loading = $mmGrid.find('.mmg-loading');
            $loading.css({
                'left': ($mmGrid.width() - $loading.width()) / 2,
                'top': ($mmGrid.height() - $loading.height()) / 2
            }).show();
        }
        , _hideLoading: function(){
            var $mmGrid = this.$mmGrid;
            $mmGrid.find('.mmg-mask').hide();
            $mmGrid.find('.mmg-loading').hide();
        }
        , _showNoData: function(){
            this._showMessage(this.opts.noDataText);
        }

        , _showLoadError: function(){
            this._showMessage(this.opts.loadErrorText);
        }

        , _showMessage: function(msg){
            var $mmGrid = this.$mmGrid;
            var $headWrapper = this.$headWrapper;
            var $message = $mmGrid.find('.mmg-message');
            $message.css({
                'left': ($mmGrid.width() - $message.width()) / 2,
                'top': ($mmGrid.height() + $headWrapper.height()  - $message.height()) / 2
            }).text(msg).show();
        }
        , _hideMessage: function(){
            var $mmGrid = this.$mmGrid;
            $mmGrid.find('.mmg-message').hide();
        }

        , _nativeSorter: function(colIndex, sortStatus){
            var leafCols = this._leafCols();
            var col = leafCols[colIndex];

            this.$body.find('tr > td:nth-child('+(colIndex+1)+')')
                .sortElements(function(a, b){
                    var av = $.text($(a));
                    var bv = $.text($(b));
                    //排序前转换
                    if(col.type === 'number'){
                        av = parseFloat(av);
                        bv = parseFloat(bv);
                    }else{
                        //各个浏览器localeCompare的结果不一致
                        return sortStatus === 'desc' ? -av.localeCompare(bv)  : av.localeCompare(bv);
                    }
                    return av > bv ? (sortStatus === 'desc' ? -1 : 1) : (sortStatus === 'desc' ? 1 : -1);
                }, function(){
                    return this.parentNode;
                });
        }

        , _refreshSortStatus: function(){
            var $ths = this.$head.find('th');
            var sortColIndex = -1;
            var sortStatus = '';
            $ths.find('.mmg-title').each(function(index, item){
                var status = $.data(item, 'sortStatus');
                if(status){
                    sortColIndex = index;
                    sortStatus = status;
                }
            });
            var sortStatus = sortStatus === 'desc' ? 'asc' : 'desc';
            if(sortColIndex >=0){
                $ths.eq(sortColIndex).find('.mmg-title').data('sortStatus',sortStatus).click();
            }
        }

        , _loadAjax: function(args){
            var that = this;
            var opts = this.opts;
            var params = {};
            //opt的params可以使函数，例如收集过滤的参数
            if($.isFunction(opts.params)){
                var p = opts.params();
                if(!p){
                    return;
                }
                params = $.extend(params, p);
            }else if($.isPlainObject(opts.params)){
                params = $.extend(params, opts.params);
            }

            if(opts.remoteSort){
                var sortName = '';
                var sortStatus = '';
                var $titles = this.$head.find('.mmg-title');
                for(var colIndex=0; colIndex<$titles.length; colIndex++){
                    var status = $.data($titles[colIndex], 'sortStatus');
                    if(status){
                        var col = $titles.eq(colIndex).parent().parent().data('col');
                        sortName = col.sortName ?
                            col.sortName : col.name;
                        sortStatus = status;
                    }
                }
                if(sortName){
                    params.sort = sortName+'.'+sortStatus;
                }
            }


            //插件参数合并
            var pluginParams = {};
            for(var i=0; i< this.opts.plugins.length; i++){
                var plugin = this.opts.plugins[i];
                $.extend(pluginParams, plugin.params());
            }
            params = $.extend(params, pluginParams);

            //合并load的参数
            params = $.extend(params, args);

			if(opts.useLoading){
				that._showLoading();
			}
            
            ajaxSubmit(this.searchBtn,{
            	method: opts.method,
                url: opts.url,
                data: jQuery.param( params, true),
                failCallback:true,
                error:function(){
                	that._hideLoading();
	                that._showLoadError();
                },
                failCallback:function(data){
                	 that._hideLoading();
                   	 that._showLoadError();
                   	 error_win(data);
                },
                callback:function(resultMsg){
                	 try{
               	 		data = $.parseJSON(resultMsg.content);
	                    //获得root对象
	                    var items = data;
	                    if($.isArray(data[opts.root])){
	                        items = data[opts.root];
	                    }
	                    that._populate(items);
	                    that._hideLoading();
	                    if(!opts.remoteSort){
	                        that._refreshSortStatus();
	                    }
	
	                    if(data && $.isArray(data[opts.root])){
	                        data = $.extend(args, data);
	                    }
	                    that.$body.triggerHandler('loadSuccess', data);
	                   
	                }catch(e){
	                    that._hideLoading();
	                    that._showLoadError();
	                    throw e;
	                }
	                
	                if(opts.callback != null && typeof opts.callback == "function"){
						opts.callback(data,resultMsg);
					}
	                	
                }
            
            });
            /**
            $.ajax({
                type: opts.method,
                url: opts.url,
                data: params,
                dataType: 'json',
                cache: opts.cache
            }).done(function(data){
                try{
                    //获得root对象
                    var items = data;
                    if($.isArray(data[opts.root])){
                        items = data[opts.root];
                    }
                    that._populate(items);
                    that._hideLoading();
                    if(!opts.remoteSort){
                        that._refreshSortStatus();
                    }

                    if(data && $.isArray(data[opts.root])){
                        data = $.extend(args, data);
                    }
                    that.$body.triggerHandler('loadSuccess', data);


                }catch(e){
                    that._hideLoading();
                    that._showLoadError();
                    throw e;
                }

            }).fail(function(data){
                that._hideLoading();
                that._showLoadError();
                that.$body.triggerHandler('loadError', data);
            });*/

        }

        , _loadNative: function(args){
            this._populate(args);
            this._refreshSortStatus();
            this.$body.triggerHandler('loadSuccess', args);
            var opts = this.opts;
            if(opts.callback != null && typeof opts.callback == "function"){
				opts.callback(args);
			}
        }
        , load: function(args){
            try{
                var opts = this.opts;
                this._hideMessage();
                this._loadCount = this._loadCount + 1 ;

                if($.isArray(args)){
                    //加载本地数据
                    this._loadNative(args);
                }else if(opts.url){
                    this._loadAjax(args);
                }else if(opts.items){
                    this._loadNative(opts.items);
                }else{
                    this._loadNative([]);
                }
                
            }catch(e){
                this._showLoadError();
                throw e;
            }
        }

        //重设尺寸
        , resize: function(){
            var opts = this.opts;
            var $mmGrid = this.$mmGrid;
            var $headWrapper = this.$headWrapper;
            var $bodyWrapper = this.$bodyWrapper;

            // fix in ie6
            if(browser.isIE6 && (!opts.width || opts.width === 'auto')){
                $mmGrid.width('100%');
                $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width()));
            }else{
                $mmGrid.width(opts.width);
            }

            if(false && opts.height !== 'auto'){
                if(browser.isIE6 && (!opts.height || opts.height === 'auto')){
                    $mmGrid.height('100%');
                    $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height()));
                }else{
                   //$mmGrid.height(opts.height);
                }
                $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true));
            }

            //调整message
            var $message = $mmGrid.find('.mmg-message');
            if($message.is(':visible')){
                $message.css({
                    'left': ($mmGrid.width() - $message.width()) / 2,
                    'top': ($mmGrid.height() + $headWrapper.height() - $message.height()) / 2
                });
            }
            //调整loading
            var $mask = $mmGrid.find('.mmg-mask');
            if($mask.is(':visible')){
                $mask.width($mmGrid.width()).height($mmGrid.height());
                var $loadingWrapper = $mmGrid.find('.mmg-loading');
                $loadingWrapper.css({
                    'left': ($mmGrid.width() - $loadingWrapper.width()) / 2,
                    'top': ($mmGrid.height() - $loadingWrapper.height()) / 2
                })
            }

            $bodyWrapper.trigger('scroll');

            this._resizeHeight();
        }

        , _resizeHeight: function(){
            var opts = this.opts;
            var $bodyWrapper = this.$bodyWrapper;
            var $body= this.$body;
            if(opts.height === 'auto' && browser.isIE7){
                $bodyWrapper.height('auto');
                if($bodyWrapper.width() < $body.width()){
                    $bodyWrapper.height($bodyWrapper.height() + $bodyWrapper.height() - $bodyWrapper[0].clientHeight  + 1);
                }
            }
        }

            //选中
        , select: function(args){
        	var that = this;
            var opts = this.opts;
            var $body = this.$body;
            var $head = this.$head;
            var singleSelect = true;
            var recordRowId = opts.recordRowId;
            var recordField = opts.recordField;

            if(typeof args === 'number'){
                var $tr = $body.find('tr').eq(args);
                var rowindex = $tr.attr("rowindex");
                if(!opts.multiSelect){
                    $body.find('tr.selected').removeClass('selected');
                    if(opts.checkCol){
                        $body.find('tr > td').find('.mmg-check').prop('checked','');
                        if(recordRowId){
	                    	this.selecteds.length = 0;
	                    }
                    }
                }
                if(!$tr.hasClass('selected')){
                	if(opts.lineRoot==undefined){
                    	$tr.addClass('selected');
                    }else{
                    	$('tr[rowindex="'+rowindex+'"]').addClass('selected');
                    }
                    
                    if(opts.checkCol){
                        $tr.find('td .mmg-check').prop('checked','checked');
                        if(recordRowId){
	                    	var row = $.data($tr[0],'item');
							if(!that.selecteds.contains(row[recordField])){
								that.selecteds.push(row[recordField]);
							}
	                    }
                    }
                }
                if(opts.onSelectRow!=null && typeof opts.onSelectRow === 'function'){
	            	opts.onSelectRow($.data($tr[0],'item'),$tr,true);
	            }
            }else if(typeof args === 'function'){
                $.each($body.find('tr'), function(index){
                    if(args($.data(this, 'item'), index)){
                        var $this = $(this);
                        if(!$this.hasClass('selected')){
                            $this.addClass('selected');
                            if(opts.checkCol){
                                $this.find('td .mmg-check').prop('checked','checked');
                                if(recordRowId){
                    				var row = $.data($this[0],'item');
									if(!that.selecteds.contains(row[recordField])){
										that.selecteds.push(row[recordField]);
									}
                    			}
                            }
                        }
                    }
                });
            }else if(args === undefined || (typeof args === 'string' && args === 'all')){
                $body.find('tr.selected').removeClass('selected');
                var $trs = $body.find('tr').addClass('selected');
                $body.find('tr > td').find('.mmg-check').prop('checked','checked');
                if(recordRowId){
                    $trs.filter(".real-row").each(function(){
	                	var row = $.data($(this)[0],'item');
						if(!that.selecteds.contains(row[recordField])){
							that.selecteds.push(row[recordField]);
						}
	                })
                }
                if(opts.onSelectAll!=null && typeof opts.onSelectAll === 'function'){
	            	opts.onSelectAll(that.selectedRows(),$trs,true);
	            }
                
            }else{
                return;
            }

            if(opts.checkCol){
                var $checks = $body.find('tr > td').find('.mmg-check');
                if($checks.length === $checks.filter(':checked').length){
                    $head.find('th .checkAll').prop('checked','checked');
                }
            }

        }
            //取消选中
        , deselect: function(args){
        	var that = this;
            var opts = this.opts;
            var $body = this.$body;
            var $head = this.$head;
            var recordRowId = opts.recordRowId;
            
            if(typeof args === 'number'){
                var $tr = $body.find('tr').eq(args);
                var rowindex = $tr.attr("rowindex");
                $('tr[rowindex="'+rowindex+'"]').removeClass('selected');
                if(opts.checkCol){
                    $body.find('tr').eq(args).find('td .mmg-check').prop('checked','');
                    if(recordRowId){
	                    var row = $.data($tr[0],'item');
						if(that.selecteds.contains(row[opts.recordField])){
							that.selecteds.removeByValue(row[opts.recordField]);
						}
	                }
                }
                
                if(opts.onSelectRow!=null && typeof opts.onSelectRow === 'function'){
	            	opts.onSelectRow($.data($tr[0],'item'),$tr,false);
	            }
            }else if(typeof args === 'function'){
                $.each($body.find('tr'), function(index){
                    if(args($.data(this, 'item'), index)){
                        $(this).removeClass('selected');
                        if(opts.checkCol){
                            $(this).find('td .mmg-check').prop('checked','');
                            if(recordRowId){
                    			var row = $.data($(this)[0],'item');
								if(that.selecteds.contains(row[opts.recordField])){
									that.selecteds.removeByValue(row[opts.recordField]);
								}
                			}
                        }
                    }
                });
            }else if(args === undefined || (typeof args === 'string' && args === 'all')){
            	var selectedRows=[];
            	if(opts.onSelectAll!=null && typeof opts.onSelectAll === 'function'){
            		selectedRows = that.selectedRows();
            	}
                var $trs = $body.find('tr.selected').removeClass('selected');
                if(opts.checkCol){
                    $body.find('tr > td').find('.mmg-check').prop('checked','');
                    if(recordRowId){
                    	var $trs_r = $trs.filter(".real-row");
                    	for(var i=0;i<$trs_r.length;i++){
                    	   var $tr = $trs_r.eq(i);
                    	   var row = $.data($tr[0],'item');
							if(this.selecteds.contains(row[opts.recordField])){
								this.selecteds.removeByValue(row[opts.recordField]);
							}         	
                    	}
                	}
                    if(opts.onSelectAll!=null && typeof opts.onSelectAll === 'function'){
		            	opts.onSelectAll(selectedRows,$trs,false);
		            }
                }
            }else{
                return;
            }

            $head.find('th .checkAll').prop('checked','');

        }
        , selectedRows: function(){
            var $body = this.$body;
            var selected = [];
            $.each($body.find('tr.selected.real-row'), function(index ,item){
                selected.push($.data(this,'item'));
            });
            return selected;
        }

        , selectedRowsIndex: function(){
            var $body = this.$body;
            var $trs = this.$body.find('tr')
            var selected = [];
            $.each($body.find('tr.selected.real-row'), function(index){
                selected.push($trs.index(this));
            });
            return selected;
        }

        , rows: function(){
            var $body = this.$body;
            var items = [];
            $.each($body.find('tr'), function(){
                items.push($.data(this,'item'));
            });
            return items;
        }

        , row: function(index){
            var $body = this.$body;
            if(index !== undefined && index >= 0){
                var $tr = $body.find('tr').eq(index);
                if($tr.length !== 0){
                    return $.data($tr[0],'item');
                }
            }
        }

        , rowsLength: function(){
            var $body = this.$body;
            var length = $body.find('tr').length;
            if(length === 1 && $body.find('tr.emptyRow').length === 1){
                return 0;
            }
            return length;
        }

        //添加数据，第一个参数可以为数组
        , addRow: function(item, index, obj){
            var $tbody = this.$body.find('tbody');

            if($.isArray(item)){
                for(var i=item.length-1; i >= 0; i--){
                    this.addRow(item[i], index,obj);
                }
                return ;
            }

            if(!$.isPlainObject(item)){
                return ;
            }

            this._hideMessage();
            this._removeEmptyRow();

            var $tr;

            if(index === undefined || index === null || index < 0){
                $tr = $(this._rowHtml(item, this.rowsLength(), obj));
                $tbody.append($tr);
            }else{
                $tr = $(this._rowHtml(item, index, obj));
                if(index === 0){
                    $tbody.prepend($tr);
                }else{
                    var $before = $tbody.find('tr').eq(index-1);
                    //找不到就插到最后
                    if($before.length === 0){
                        $tbody.append($tr);
                    }else{
                        $before.after($($tr));
                    }
                }
            }
            $tr.data('item', item);
            this._setStyle();


            this.$body.triggerHandler('rowInserted', [item, index]);
        }
        , addRows: function(items, index, obj){
            var $tbody = this.$body.find('tbody');

            if(!$.isArray(items)){
            	return;
            }
          

            this._hideMessage();
            this._removeEmptyRow();
            
            for(var i=items.length-1; i >= 0; i--){
            	var item = items[i];
                var $tr;
	            if(index === undefined || index === null || index < 0){
	                $tr = $(this._rowHtml(item, this.rowsLength(), obj));
	                $tbody.append($tr);
	            }else{
	                $tr = $(this._rowHtml(item, index, obj));
	                if(index === 0){
	                    $tbody.prepend($tr);
	                }else{
	                    var $before = $tbody.find('tr').eq(index-1);
	                    //找不到就插到最后
	                    if($before.length === 0){
	                        $tbody.append($tr);
	                    }else{
	                        $before.after($($tr));
	                    }
	                }
	            }
	            $tr.data('item', item);
	            this.$body.triggerHandler('rowInserted', [item, index]);
            }
            this._setStyle();
        }
        , addEmptyRow: function(index, obj){
            var $tbody = this.$body.find('tbody');
            var $tr = '<tr class="emptyRow"><td  style="border: 0px;background: none;">&nbsp;</td></tr>';

            if(index === undefined || index === null || index < 0){
                $tbody.append($tr);
            }else{
                if(index === 0){
                    $tbody.prepend($tr);
                }else{
                    var $before = $tbody.find('tr').eq(index-1);
                    //找不到就插到最后
                    if($before.length === 0){
                        $tbody.append($tr);
                    }else{
                        $before.after($($tr));
                    }
                }
            }
            var item = {};
            $tr.data('item', item);
            this._setStyle();


            this.$body.triggerHandler('rowInserted', [item, index]);
            
        }
        //更新行内容，两个参数都必填
        , updateRow: function(item, index){
            var opts = this.opts;
            var $tbody = this.$body.find('tbody');
            if(!$.isPlainObject(item)){
                return ;
            }
            var oldItem = this.row(index);

            var $tr = $tbody.find('tr').eq(index);
            var checked = $tr.find('td:first :checkbox').is(':checked');
            $tr.html(this._rowHtml(item, index).slice(4,-5));
            if(opts.checkCol){
                $tr.find('td:first :checkbox').prop('checked',checked);
            }

            $tr.data('item', item);
            this._setStyle();

            this.$body.triggerHandler('rowUpdated', [oldItem, item, index]);
        }

        //删除行，参数可以为索引数组
        , removeRow: function(index){
            var that = this;
            var $tbody = that.$body.find('tbody');

            if($.isArray(index)){
                for(var i=index.length-1; i >= 0; i--){
                    that.removeRow(index[i]);
                }
                return ;
            }

            if(index === undefined){
                var $trs = $tbody.find('tr');
                for(var i=$trs.length-1; i >= 0; i--){
                    that.removeRow(i);
                }
            }else{
                var item = that.row(index);
                $tbody.find('tr').eq(index).remove();
                this.$body.triggerHandler('rowRemoved', [item, index]);
            }
            this._setStyle();
            if(this.rowsLength() === 0){
                this._showNoData();
                this._insertEmptyRow();
            }
        },serializeSelectedIds :function(param){
			var ids = 'ids';
			if(param!=undefined){
				ids = param;
			}
			var rows = this.selectedRows();
			var str = "";
			for(var i=0;i<rows.length;i++){
				var row = rows[i];
				str+="&"+ids+"="+row.id;
			}	
			var len = str.length;
			if(len>0){
				str = str.substring(1,len);
			}
			return str;
			
		},
		clearSelecteds:function(){
			this.selecteds.length = 0;
		}
    };

    $.fn.mmGrid = function(){
    	$(this).closest("form").attr("onkeydown","if(event.keyCode==13){return false;}");
        if(arguments.length === 0 || typeof arguments[0] === 'object'){
            var option = arguments[0]
                , data = this.data('mmGrid')
                , options = $.extend(true, {}, $.fn.mmGrid.defaults, option);
            if (!data) {
                data = new MMGrid(this, options);
                this.data('mmGrid', data);
            }
            return $.extend(true, this, data);
        }
        if(typeof arguments[0] === 'string'){
            var data = this.data('mmGrid');
            var fn =  data[arguments[0]];
            if(fn){
                var args = Array.prototype.slice.call(arguments);
                return fn.apply(data,args.slice(1));
            }
        }
    };

    $.fn.mmGrid.defaults = {
        width: 'auto'
        , height: 'fill'
        , cols: []
        , url: false
        , params: {}
        , method: 'POST'
        , cache: false
        , root: 'content'
        , items: []
        , autoLoad: false
        , remoteSort: false
        , sortName: ''
        , sortStatus: 'asc'
        , loadingText: ''
        , noDataText: ''
        , loadErrorText: ''
        , useLoading: true
        , multiSelect: true
        , checkCol: true
        , indexCol: false
        , indexColWidth: 30
        , fullWidthRows: false
        , nowrap: true
        , showBackboard: true
        , bindSearchBtn:true
        , checkByClickTd: false
        , backboardMinHeight: 125
        , useCountText: true
        , rowCursorPointer:false
        , hideHead:false
        , recordRowId:false
        , recordField:'id'
        , onSelectAll:null
        , onSelectRow:null
        , plugins : [] //插件 插件必须实现 init($mmGrid)和params()方法，参考mmPaginator
    };
//  event : loadSuccess(e,data), loadError(e, data), cellSelected(e, item, rowIndex, colIndex)
//          rowInserted(e,item, rowIndex), rowUpdated(e, oldItem, newItem, rowIndex), rowRemoved(e,item, rowIndex)
//


    $.fn.mmGrid.Constructor = MMGrid;


    // see: http://james.padolsey.com/javascript/sorting-elements-with-jquery/
    $.fn.sortElements = (function(){
        var sort = [].sort;
        return function(comparator, getSortable) {
            getSortable = getSortable || function(){return this;};
            var placements = this.map(function(){
                var sortElement = getSortable.call(this),
                    parentNode = sortElement.parentNode,
                    nextSibling = parentNode.insertBefore(
                        document.createTextNode(''),
                        sortElement.nextSibling
                    );
                return function() {
                    if (parentNode === this) {
                        throw new Error(
                            "You can't sort elements if any one is a descendant of another."
                        );
                    }
                    parentNode.insertBefore(this, nextSibling);
                    parentNode.removeChild(nextSibling);
                };
            });
            return sort.call(this, comparator).each(function(i){
                placements[i].call(getSortable.call(this));
            });
        };
    })();
}(window.jQuery);


/**分页*/
!function($){
    var MMPaginator = function(element, options){
        this.$el = $(element);
        this.opts = options;
        //this.$mmGrid.$mmPaginator = this.$el;
    };

    MMPaginator.prototype = {
        _initLayout: function(){
            var that = this;
            var $el = this.$el;
            var opts = this.opts;

            $el.addClass("mmPaginator");
            var pgHtmls = [
                '<div class="totalCountLabel" style="display:none;"></div>',
                '<ul class="pageList"></ul>',
                '<div class="limit" style="display:none;"><select></select></div>'
            ];
            $el.append($(pgHtmls.join('')));

            this.$totalCountLabel = $el.find('.totalCountLabel');
            this.$pageList = $el.find('.pageList');
            this.$limitList = $el.find('.limit select');
			
             var $limitList = this.$limitList;
            $.each(opts.limitList, function(){
                var $option = $('<option></option>')
                    .prop('value',this)
                    .text(that.formatString(opts.limitLabel,[this]));
                $limitList.append($option);
            });

            $limitList.on('change', function(){
                $el.data('page', 1);
                that.$mmGrid.load();
            });

        }

        , _plain: function(page, totalCount, limit){
            var that = this;
            var $el = this.$el;
            var $pageList = this.$pageList;

            var totalPage = totalCount % limit === 0 ? parseInt(totalCount/limit) : parseInt(totalCount/limit) + 1;
            totalPage = totalPage ? totalPage : 0;
            if(totalPage === 0){
                page = 1;
            }else if(page > totalPage){
                page = totalPage;
            }else if(page < 1 && totalPage != 0){
                page = 1;
            }
            //
            var $prev = $('<li  href="javascript:void(0);" class="prev" title="上一页"><a></a></li>');
            if(page<=1){
                $prev.addClass('disable');
            }else{
                $prev.find('a').on('click', function(){
                    $el.data('page', page-1);
                    that.$mmGrid.load();
                });
            }
            $pageList.append($prev);
            /////
            var list = [1];
            if(page > 4 ){
                list.push('...');
            }
            for(var i= 0; i < 5; i++){
                var no = page - 2 + i;
                if(no > 1 && no <= totalPage-1){
                    list.push(no);
                }
            }
            if(page+1 < totalPage-1){
                list.push('...');
            }
            if(totalPage>1){
                list.push(totalPage);
            }
            $.each(list, function(index, item){
                var $li = $('<li><a></a></li>');
                if(item === '...'){
                    $li.addClass('').html('...');
                }else if(item === page){
                    $li.addClass('active').find('a').text(item);
                }else{
                    $li.find('a').text(item).prop('title','第'+item+'页').on('click', function(e){
                        $el.data('page', item);
                        that.$mmGrid.load();
                    });
                }
                $pageList.append($li);
            });
            //
            var $next = $('<li class="next"><a href="javascript:void(0);" title="下一页"></a></li>');
            if(page>=totalPage){
                $next.addClass('disable');
            }else{
                $next.find('a').on('click', function(){
                    $el.data('page', page+1);
                    that.$mmGrid.load();
                });
            }
            $pageList.append($next);
        }

        , _search: function(page, totalCount, limit){

        }

        , load: function(params){
            var $el = this.$el;
            var $limitList = this.$limitList;
            var opts = this.opts;

            if(!params){
                params = {};
            }

            var page = params[opts.pageParamName];
            if(page === undefined || page === null){
                page = $el.data('page');
            }
            $el.data('page', page);

            var totalCount = params[opts.totalCountName];
            if(totalCount === undefined){
                totalCount = 0;
            }
            $el.data('totalCount', totalCount);

            var limit = params[opts.limitParamName];
            if(!limit){
                limit = $limitList.val();
            }
            this.$limitList.val(limit);

            this.$totalCountLabel.html(this.formatString(opts.totalCountLabel,[totalCount]));
            this.$pageList.empty();

            this._plain(page, totalCount, this.$limitList.val());
        }

        , formatString: function(text, args){
            return text.replace(/{(\d+)}/g, function(match, number) {
                return typeof args[number] != 'undefined'
                    ? args[number]
                    : match
                    ;
            });
        }

        , params: function(){
            var opts = this.opts;
            var $el = this.$el;
            var $limitList = this.$limitList;

            var params = {};
            params[opts.pageParamName] = $el.data('page');
            params[opts.limitParamName] = $limitList.val();
            return params;
        }

        , init: function($grid,e){
        
        	e.$mmPaginator = this.$el;
            var that = this;
            var opts = that.opts;
            this.$mmGrid = $grid;
            this._initLayout();
            this.$mmGrid.on('loadSuccess', function(e, data){
                that.load(data);
            });

            var params = {};
            params[opts.totalCountName] = 0;
            params[opts.pageParamName] = opts.page;
            params[opts.limitParamName] = opts.limit;
            this.load(params);

            if($grid.opts.indexCol){
                var indexCol = $grid.opts.cols[0];
                indexCol.renderer = function(val,item,rowIndex){
                    var params = that.params();
                    return '<label class="mmg-index">' +
                        (rowIndex + 1 + ((params[opts.pageParamName]-1) * params[opts.limitParamName])) +
                        '</label>';
                };
            }

        }

    };

    $.fn.mmPaginator = function(){

        if(arguments.length === 0 || typeof arguments[0] === 'object'){
            var option = arguments[0]
                , data = this.data('mmPaginator')
                , options = $.extend(true, {}, $.fn.mmPaginator.defaults, option);
            if (!data) {
                data = new MMPaginator(this[0], options);
                this.data('mmPaginator', data);
            }
            return $.extend(true, this, data);
        }
        if(typeof arguments[0] === 'string'){
            var data = this.data('mmPaginator');
            var fn =  data[arguments[0]];
            if(fn){
                var args = Array.prototype.slice.call(arguments);
                return fn.apply(data,args.slice(1));
            }
        }
    };

    $.fn.mmPaginator.defaults = {
         style: 'plain'
        , totalCountName: 'total'
        , page: 1
        , pageParamName: 'pageNumber'
        , limitParamName: 'pageSize'
        , limitLabel: '每页{0}条'
        , totalCountLabel: '共<span>{0}</span>条记录'
        , limit: 100
        , limitList: [100]
    };

    $.fn.mmPaginator.Constructor = MMPaginator;

}(window.jQuery);

function serializeSelectedIds(param){
	var ids = 'ids';
	if(param!=undefined){
		ids = param;
	}
	var rows = mmg.selectedRows();
	var str = "";
	for(var i=0;i<rows.length;i++){
		var row = rows[i];
		str+="&i"+ids+"="+row.id;
	}	
	var len = str.length;
	if(len>0){
		str = str.substring(1,len);
	}
	return str;
	
}

function _handleNullStr(val){
	var str = val;
	if(str==null){
		str='';
	}
	return str;
}
